import tensorflow as tf
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
# 方法1: 设置matplotlib支持中文
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
# 设置随机种子以确保结果可重现
tf.random.set_seed(42)
np.random.seed(42)

# 1. 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris.data  # 特征
y = iris.target  # 目标变量

# 2. 数据预处理
# 标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 将标签转换为分类格式（one-hot编码）
y_categorical = tf.keras.utils.to_categorical(y, num_classes=3)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X_scaled, y_categorical, test_size=0.2, random_state=42, stratify=y
)

# 3. 构建神经网络模型
model = tf.keras.Sequential([
    tf.keras.layers.Dense(64, activation='relu', input_shape=(4,)),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(3, activation='softmax')  # 输出层，3个类别
])

# 4. 编译模型
model.compile(
    optimizer='adam',
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

# 5. 训练模型
history = model.fit(
    X_train, y_train,
    epochs=100,
    batch_size=16,
    validation_split=0.2,
    verbose=1
)

# 6. 评估模型
test_loss, test_accuracy = model.evaluate(X_test, y_test, verbose=0)
print(f"测试集准确率: {test_accuracy:.4f}")

# 7. 绘制训练过程
plt.figure(figsize=(12, 4))

plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='训练准确率')
plt.plot(history.history['val_accuracy'], label='验证准确率')
plt.title('模型准确率')
plt.xlabel('迭代次数')
plt.ylabel('准确率')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='训练损失')
plt.plot(history.history['val_loss'], label='验证损失')
plt.title('模型损失')
plt.xlabel('迭代次数')
plt.ylabel('损失')
plt.legend()

plt.tight_layout()
plt.show()

# 8. 进行预测示例
# 随机选择几个测试样本进行预测
sample_indices = np.random.choice(len(X_test), 5, replace=False)
sample_data = X_test[sample_indices]
sample_labels = y_test[sample_indices]

predictions = model.predict(sample_data)
predicted_classes = np.argmax(predictions, axis=1)
true_classes = np.argmax(sample_labels, axis=1)

print("\n预测示例:")
for i in range(len(sample_data)):
    print(f"样本 {i+1}: 预测类别 = {predicted_classes[i]}, 真实类别 = {true_classes[i]}")